#!/usr/bin/env node

// LEGACY SCRIPT
// This script is considered legacy as it is meant to be
// replaced by stable-branch-sync.yml GitHub Action in
// the future. However, it is kept for now as a backup
// and for manual use if needed.

// USAGE:
// Simply run `yarn stable-sync` from any branch.
// This will create/update a local stable-sync branch
// and get it in the state needed for a stable-sync PR
// Once the script successfully completes, you just
// need to push the branch to the remote repo. This will
// likely require a `git push --force`

const { promisify } = require('util');
const exec = promisify(require('child_process').exec);

async function runGitCommands() {
  const branchName = 'stable-sync';

  try {
    try {
      // Check if the branch already exists
      const { stdout: branchExists } = await exec(
        `git rev-parse --quiet --verify ${branchName}`,
      );
      if (branchExists.trim()) {
        // Branch exists, so simply check it out
        await exec(`git checkout ${branchName}`);
        console.log(`Checked out branch: ${branchName}`);
      } else {
        throw new Error(
          'git rev-parse --quiet --verify failed. Branch hash empty',
        );
      }
    } catch (error) {
      if (error.stdout === '') {
        console.warn(
          `Branch does not exist, creating new ${branchName} branch.`,
        );

        // Branch does not exist, create and check it out
        await exec(`git checkout -b ${branchName}`);
        console.log(`Created and checked out branch: ${branchName}`);
      } else {
        console.error(`Error: ${error.message}`);
        process.exit(1);
      }
    }

    await exec('git fetch');
    console.log('Executed: git fetch');

    await exec('git reset --hard origin/stable');
    console.log('Executed: git reset --hard origin/stable');

    try {
      await exec('git merge origin/main');
      console.log('Executed: git merge origin/main');
    } catch (error) {
      // Handle the error but continue script execution
      if (
        error.stdout.includes(
          'Automatic merge failed; fix conflicts and then commit the result.',
        )
      ) {
        console.warn(
          'Merge conflict encountered. Continuing script execution.',
        );
      } else {
        console.error(`Error: ${error.message}`);
        process.exit(1);
      }
    }

    await exec('git add .');
    await exec('git restore --source origin/main .');
    console.log('Executed: it restore --source origin/main .');

    await exec('git checkout origin/main -- .');
    console.log('Executed: git checkout origin/main -- .');

    await exec('git checkout origin/stable -- CHANGELOG.md');
    console.log('Executed: git checkout origin/stable -- CHANGELOG.md');

    await exec('git add .');
    console.log('Executed: git add .');

    await exec(
      'git commit -m "Merge origin/main into stable-sync" --no-verify',
    );
    console.log('Executed: git commit');

    // Force push since stable-sync is a temporary branch that gets hard reset
    await exec(
      'git push --force-if-includes --set-upstream origin stable-sync',
    );
    console.log(
      'Executed: git push --force-if-includes --set-upstream origin stable-sync',
    );

    console.log('Your local stable-sync branch is now ready to become a PR.');
  } catch (error) {
    console.error(`Error: ${error.message}`);
    process.exit(1);
  }
}

runGitCommands();
